'''
    Code Name: Python Pong 3D
    
    Module: PyPong.Ball
    Filename:  __init__.py
    
    Developed by: Juan C. Montes
    
    Created on 26/03/2009
'''


# Referencias de OGRE
import ogre.renderer.OGRE as ogre
import ogre.sound.OgreAL as ogreal

# Referencias del proyecto
import PyPong


''' Clase principal de control de la bola '''
class Ball:   
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Constructor    
    '''  
    def __init__(self, scenemanager, parent):
        # Definimos los objetos
        self.scenemanager = ogre.SceneManager
        self.node = ogre.SceneNode
        self.parent = parent
        
        # Preparamos el sonido        
        self.sound = ogreal.SoundManager()
        self.soundPoint = self.sound.createSound("point", "cheer.wav", 
                                                 False, False)
        self.soundWall = self.sound.createSound("wall", "wallSound.wav", 
                                                False, False)
        self.soundPaddle = self.sound.createSound("paddle", "paddleSound.wav", 
                                                  False, False)                                                
        
        
        # Definimos las constantes
        self.CPU_PADDLE_DOWN = ogre.Vector3(0, -0.1, 0)
        self.CPU_PADDLE_UP = ogre.Vector3(0, 0.1, 0)
        
        # Guardamos la escena        
        self.scenemanager = scenemanager
        
        # Ajustamos la velocidad inicial
        self.speed = 100
        
        # Ajustamos la direccion inicial
        self.direction = ogre.Vector3(1, -1, 0)            
    
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: addToScene
    Descript: Situa la bola en la escena
    ''' 
    def addToScene(self):
        # Creamos la bola y la situamos en la escena
        ent = self.scenemanager.createEntity("Ball", "sphere.mesh")
        ent.setMaterialName("ball")
        self.node = self.scenemanager.getRootSceneNode().createChildSceneNode(
                    "Ball")
        self.node.attachObject(ent)
        self.node.setScale(0.05, 0.05, 0.05)
    
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: moveBall
    Descript: Mueve la bola por la pantalla
    ''' 
    def moveBall(self, timeSinceLastFrame, CPU):        
        # Movemos la bola
        self.node.translate(self.direction * self.speed * timeSinceLastFrame)
        
        # Actualizamos la posicion de la bola
        pos = self.node.getPosition()
        
        # Controlamos si hemos sobrepasado el muro izq
        if (pos.x -5) <= -92.5:
            # Situamos la bola en el centro
            self.node.setPosition(0, 0, 0)
            self.speed = 100
            
            # Aumentamos los puntos de la CPU
            self.parent.cpuScore += 1
            self.parent.updateScore()
            
            # Ponemos un sonido
            self.soundPoint.play()                        
            
        elif (pos.x +5) >= 92.5:
            # Situamos la bola en el centro
            self.node.setPosition(0, 0, 0)
            
            # Aumentamos los puntos del jugador
            self.parent.playerScore += 1
            self.parent.updateScore()            
                        
            # Ponemos un sonido
            self.soundPoint.play()  
            
        elif (pos.y - 5) <= -67.5 and self.direction.y < 0:
            # Situamos la bola en el muro
            self.node.setPosition(pos.x, (-67.5 + 5), pos.z)
            
            # Ponemos un sonido
            self.soundWall.play()            
            
            # Cambiamos la direccion de la bola
            self.reverseVerticalDirection()
        elif (pos.y + 5) >= 67.5 and self.direction.y > 0:
            # Situamos la bola en el muro
            self.node.setPosition(pos.x, (67.5 - 5), pos.z)
            
            # Ponemos un sonido
            self.soundWall.play()
            
            # Cambiamos la direccion de la bola
            self.reverseVerticalDirection()
    
        # Movemos la barra de la CPU
        if self.direction.x > 0:
            if self.getPosition().y > CPU.getPosition().y:
                CPU.movePaddle(self.CPU_PADDLE_UP)
            elif self.getPosition().y < CPU.getPosition().y:
                CPU.movePaddle(self.CPU_PADDLE_DOWN)
        
                
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: reverseHorizontalDirection
    Descript: Invierte la posicion horizontal de la direccion
    '''     
    def reverseHorizontalDirection(self):
        self.direction *= ogre.Vector3(-1, 1, 1)
        self.speed += 2
        

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: reverseVerticalDirection
    Descript: Invierte la posicion vertical de la direccion
    '''       
    def reverseVerticalDirection(self):
        self.direction *= ogre.Vector3(1, -1, 1)
        self.speed += 2
            

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: hitPaddle
    Descript: Control de colisiones
    '''      
    def hitPaddle(self):
        # Obtenemos la posicion de la bola y las barras
        leftPaddle = self.scenemanager.getSceneNode(
                        "LeftPaddle").getPosition()
        rightPaddle = self.scenemanager.getSceneNode(
                        "RightPaddle").getPosition()
        mainBall = self.getPosition()
        
        # Controlar si la bola esta en el rango de la barra izq
        if (mainBall.x - 5) < (leftPaddle.x + 1):            
            # Comprobamos si hay colisiones
            if (((mainBall.y - 5) < leftPaddle.y + 15) and 
                ((mainBall.y + 5) > leftPaddle.y - 15)):
                # Invertimos la direccion
                self.reverseHorizontalDirection()
                
                # Situamos la bola justo en la barra
                self.node.setPosition(leftPaddle.x + 6, mainBall.y, mainBall.z)
                
                # Ponemos un sonido
                self.soundPaddle.play()                
       
        # Controlar si la bola esta en el rango de la barra der            
        elif (mainBall.x + 5) > (rightPaddle.x - 1):
            # Comprobamos si hay colisiones
            if (((mainBall.y - 5) < rightPaddle.y + 15) and 
                ((mainBall.y + 5) > rightPaddle.y - 15)):
                # Invertimos la direccion
                self.reverseHorizontalDirection()
                
                # Situamos la bola justo en la barra
                self.node.setPosition(rightPaddle.x - 6, mainBall.y, mainBall.z)
                
                # Ponemos un sonido
                self.soundPaddle.play()              
        

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: changeSpeed
    Descript: Cambia la velocidad de la bola
    '''      
    def changeSpeed(self, newspeed):
        # Controlamos la velocidad max y min
        if (self.speed <= 200) and (self.speed >= 10):
            self.speed += newspeed
        elif self.speed < 10:
            self.speed = 10
        elif self.speed > 200:
            self.speed = 200 
        

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function: getPosition
    Descript: Devuelve la posicion de la bola
    '''        
    def getPosition(self):
        return self.node.getPosition()
        
    
     
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        